package org.langqiao.network;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;

public class MutilDown {

	public static void main(String[] args) {
		final int DOWN_THREAD_NUM = 4;
		final String OUT_FILE_NAME = "down.jpg";
		InputStream[] isArr = new InputStream[DOWN_THREAD_NUM];
		RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];
		try{
			URL url = new URL("http://images.china-pub.com/ebook35001-40000/35850/shupi.jpg");
			isArr[0] = url.openStream();
			long fileLen = getFileLength(url);
			System.out.println("网络资源的大小为："+fileLen);
			outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw");
			for(int i=0;i<fileLen;i++){
				outArr[0].write(0);
			}
			
			//每个线程下载的资源数
			long numPerThread = fileLen / DOWN_THREAD_NUM;
			
			//整个线程下载完后，剩余的资源数
			long left = fileLen % DOWN_THREAD_NUM;
			
			for(int i=0;i < DOWN_THREAD_NUM;i++){
				
				if(i != 0){
					isArr[i] = url.openStream();
					outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
				}
				
				if(i == (DOWN_THREAD_NUM-1)){
					new DownThread(i * numPerThread , (i+1) * numPerThread +left ,isArr[i] , outArr[i]).start(); 
				}else{
					new DownThread(i * numPerThread , (i+1) * numPerThread ,isArr[i] , outArr[i]).start(); 
				}
			}
		}catch(Exception e){
			
		}
	}
	
	public static long getFileLength(URL url) throws IOException{
		URLConnection connection = url.openConnection();
		long length = connection.getContentLength();
		return length;
	}
}

class DownThread extends Thread{
	
	private final int BUFF_LEN = 32;//定义字节数组的长度
	
	private long start ; //定义下载的起始点
	
	private long end; //定义下载的终止点
	
	private InputStream in;//下载资源对应的输入流
	
	private RandomAccessFile raf;//下载到的字节输出到raf中
	
	public DownThread(long start , long end , InputStream in , RandomAccessFile raf){
		System.out.println(start + "----->" +end);
		this.start = start ;
		this.end = end ;
		this.in = in ;
		this.raf = raf ;
	}
	
	public void run(){
		try{
			in.skip(start);
			raf.seek(start);
			
			//定义读取输入流内容的缓存数组
			byte[] buff = new byte[BUFF_LEN];
			
			//本线程下载的资源的大小
			long contentLen = end - start ;
			
			//定义最多读几次，可以完成本次下载
			long times = contentLen/BUFF_LEN + 4 ;
			
			//定义实际读取的字节数
			int hasRead = 0 ;
			
			for(int i=0; i<times; i++){
				hasRead = in.read(buff);
				
				//如果读取的字节数<0，则退出循环
				if(hasRead < 0){
					break;
				}
				
				raf.write(buff, 0, hasRead);
			}
		}catch(Exception e){
			
		}finally{
			if(in != null){
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(raf != null){
				try {
					raf.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
